package com.mall.shopping.services;

import com.alibaba.fastjson.JSON;
import com.mall.shopping.ICartService;
import com.mall.shopping.constant.GlobalConstants;
import com.mall.shopping.constants.ShoppingRetCode;
import com.mall.shopping.converter.CartItemConverter;
import com.mall.shopping.dal.entitys.Item;
import com.mall.shopping.dal.persistence.ItemMapper;
import com.mall.shopping.dto.*;
import com.mall.shopping.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Service;
import org.redisson.api.RMap;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Slf4j
@Service(cluster = "failfast")
public class CartServiceImpl implements ICartService {

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ItemMapper itemMapper;

    //获得购物车列表
    @Override
    public CartListByIdResponse getCartListById(CartListByIdRequest request) {

        CartListByIdResponse cartListByIdResponse = new CartListByIdResponse();
        try {
            request.requestCheck();

            cartListByIdResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
//            cartListByIdResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());
            cartListByIdResponse.setMsg("success");

            RMap<Object, Object> map = redissonClient.getMap(generatorCartItemKey(request.getUserId()));
            Collection<Object> cartMaptoList = map.values();

//            List<CartProductDto> cartProductDtos = cartListByIdResponse.getCartProductDtos();

            List<CartProductDto> cartProductDtoList = new ArrayList<>();
            for (Object value : cartMaptoList) {
                CartProductDto cartProductDto = JSON.parseObject(value.toString(), CartProductDto.class);
                cartProductDtoList.add(cartProductDto);
            }
            cartListByIdResponse.setCartProductDtos(cartProductDtoList);
        } catch (Exception e) {
            log.error("CartServiceImpl.getCartListById 发生错误 :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(cartListByIdResponse, e);
        }

        return cartListByIdResponse;
    }


    private String generatorCartItemKey(long userId) {
        return GlobalConstants.CART_ITEM_CACHE_PREFIX + ":" + userId;
    }


    //添加物品到购物车
    @Override
    public AddCartResponse addToCart(AddCartRequest addCartRequest) {

        AddCartResponse addCartResponse = new AddCartResponse();

        try {
            addCartRequest.requestCheck();

            addCartResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            addCartResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

            RMap<Object, Object> map = redissonClient.getMap(generatorCartItemKey(addCartRequest.getUserId()));
            boolean b = map.containsKey(addCartRequest.getItemId());
            CartProductDto cartProductDto = null;
            if (b) {
                Object o = map.get(addCartRequest.getItemId());
                cartProductDto = JSON.parseObject(o.toString(), CartProductDto.class);
                cartProductDto.setProductNum(cartProductDto.getProductNum() + addCartRequest.getNum());
//                map.put(cartProductDto.getProductId(), JSON.toJSON(cartProductDto));
            } else {
                Item item = itemMapper.selectByPrimaryKey(addCartRequest.getItemId());
                if (item == null) {
                    addCartResponse.setCode(ShoppingRetCode.DB_EXCEPTION.getCode());
                    addCartResponse.setMsg(ShoppingRetCode.DB_EXCEPTION.getMessage());
                    return addCartResponse;
                }
                cartProductDto = CartItemConverter.item2Dto(item);
                cartProductDto.setChecked("true");//是否选中
                cartProductDto.setProductNum(addCartRequest.getNum().longValue());
            }
            map.put(addCartRequest.getItemId(), JSON.toJSON(cartProductDto));
        } catch (Exception e) {
            log.error("CartServiceImpl.addToCart 发生错误 :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(addCartResponse, e);
        }
        return addCartResponse;
    }

    @Override
    //更新购物⻋中的商品
    public UpdateCartNumResponse updateCartNum(UpdateCartNumRequest request) {

        UpdateCartNumResponse updateCartNumResponse = new UpdateCartNumResponse();
        try {
            request.requestCheck();
            updateCartNumResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            updateCartNumResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

            RMap<Object, Object> map = redissonClient.getMap(generatorCartItemKey(request.getUserId()));
            //更新商品的数据为0，则删除直接返回response
            if (request.getNum() == 0) {
                map.remove(request.getItemId());
                return updateCartNumResponse;
            }
            //查看商品是否存在
            //存在就更改num（此时num一定不为0）
            //不存在，就在商品库里查找，添加到map里面去
            boolean b = map.containsKey(request.getItemId());
            CartProductDto cartProductDto;
            if (b) {
                Object o = map.get(request.getItemId());
                cartProductDto = JSON.parseObject(o.toString(), CartProductDto.class);
                cartProductDto.setProductNum(request.getNum().longValue());
                cartProductDto.setChecked(request.getChecked());
                map.put(request.getItemId(), JSON.toJSON(cartProductDto));
            } else {
                Item item = itemMapper.selectByPrimaryKey(request.getItemId());
                if (item == null) {
                    updateCartNumResponse.setCode(ShoppingRetCode.DB_EXCEPTION.getCode());
                    updateCartNumResponse.setMsg(ShoppingRetCode.DB_EXCEPTION.getMessage());
                    return updateCartNumResponse;
                }
                cartProductDto = CartItemConverter.item2Dto(item);
                cartProductDto.setChecked("true");//是否选中
                cartProductDto.setProductNum(request.getNum().longValue());
                map.put(request.getItemId(), JSON.toJSON(cartProductDto));
            }

        } catch (Exception e) {
            log.error("CartServiceImpl.updateCartNum Occur Exception :" + e);
            ExceptionProcessorUtils.wrapperHandlerException(updateCartNumResponse, e);
        }
        return updateCartNumResponse;
    }

    @Override
    public CheckAllItemResponse checkAllCartItem(CheckAllItemRequest request) {

        return null;
    }

    @Override
    public DeleteCartItemResponse deleteCartItem(DeleteCartItemRequest request) {
        DeleteCartItemResponse deleteCartItemResponse = new DeleteCartItemResponse();

        try {
            request.requestCheck();
            deleteCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            deleteCartItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

            RMap<Object, Object> map = redissonClient.getMap(generatorCartItemKey(request.getUserId()));
            map.remove(request.getItemId());

        } catch (Exception e) {
            log.error("CartServiceImpl.deleteCartItem Occur Exception :" + e);
            deleteCartItemResponse.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
            deleteCartItemResponse.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            ExceptionProcessorUtils.wrapperHandlerException(deleteCartItemResponse, e);
        }

        return deleteCartItemResponse;

    }

    @Override
    public DeleteCheckedItemResposne deleteCheckedItem(DeleteCheckedItemRequest request) {

        DeleteCheckedItemResposne deleteCheckedItemResposne = new DeleteCheckedItemResposne();

        try {
            request.requestCheck();
            deleteCheckedItemResposne.setCode(ShoppingRetCode.SUCCESS.getCode());
            deleteCheckedItemResposne.setMsg(ShoppingRetCode.SUCCESS.getMessage());

            RMap<Object, Object> map = redissonClient.getMap(generatorCartItemKey(request.getUserId()));

            for (Object value : map.values()) {
                CartProductDto cartProductDto = JSON.parseObject(value.toString(), CartProductDto.class);
                if ("true".equals(cartProductDto.getChecked())) {
                    log.info("CartServiceImpl.delete Checked Item:" + cartProductDto.getProductId());
                    map.remove(cartProductDto.getProductId());

                }
            }

        } catch (Exception e) {
            log.error("CartServiceImpl.deleteCartItem Occur Exception :" + e);
            deleteCheckedItemResposne.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
            deleteCheckedItemResposne.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            ExceptionProcessorUtils.wrapperHandlerException(deleteCheckedItemResposne, e);
        }

        return deleteCheckedItemResposne;

    }

    @Override
    public ClearCartItemResponse clearCartItemByUserID(ClearCartItemRequest request) {

        ClearCartItemResponse clearCartItemResponse = new ClearCartItemResponse();
        try {
            request.requestCheck();
            clearCartItemResponse.setCode(ShoppingRetCode.SUCCESS.getCode());
            clearCartItemResponse.setMsg(ShoppingRetCode.SUCCESS.getMessage());

            RMap<Object, Object> map = redissonClient.getMap(generatorCartItemKey(request.getUserId()));

            List<Long> productIds = request.getProductIds();
            for (Long productId : productIds) {
                map.remove(productId);
            }
        } catch (Exception e) {
            log.error("CartServiceImpl.deleteCartItem Occur Exception :" + e);
            clearCartItemResponse.setCode(ShoppingRetCode.SYSTEM_ERROR.getCode());
            clearCartItemResponse.setMsg(ShoppingRetCode.SYSTEM_ERROR.getMessage());
            ExceptionProcessorUtils.wrapperHandlerException(clearCartItemResponse, e);
        }

        return null;
    }
}
